package com.itheima.server;

import com.itheima.entity.Poker;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import javax.websocket.EncodeException;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.util.*;
import java.util.concurrent.CopyOnWriteArraySet;

@Service
@ServerEndpoint("/api/websocket/{roomid}/{sid}")
@Slf4j
public class WebSocketServer {

    private Session session;

    private String roomid;

    private String sid;

    private Poker poker;



    // 存放每个客户端对应的MyWebSocket对象
    private static CopyOnWriteArraySet<WebSocketServer> webSocketSet = new CopyOnWriteArraySet<>();

    @OnOpen
    public void onOpen(Session session, @PathParam("roomid") String roomid, @PathParam("sid") String sid) {
        this.session = session;
        this.roomid = roomid;
        this.sid = sid;
        boolean reconnect = false;
        try {
//            this.session.getBasicRemote().sendText("连接成功，房间号："+roomid+",用户ID："+sid);
            System.out.println("连接成功，房间号："+roomid+",用户ID："+sid);
            boolean flag = false;
            for (WebSocketServer item : webSocketSet) {
                if (item.roomid.equals(roomid)  && item.poker != null && !item.sid.equals(sid) && item.poker.getCount() < 3) {
                    // 统计房间人数
                    item.poker.setCount(item.poker.getCount() + 1);
                    // 同一房间人拿到同一个poker
                    this.poker = item.poker;

                    // 随机发牌 并把牌设置到poker对象里面
                    List<Integer> init = init(this.poker.getStore());
                    this.poker.getMap().put(Integer.parseInt(sid), init);

                    // 按入房间顺序 添加至顺序
                    this.poker.getOrder().add(Integer.parseInt(sid));
                    flag = true;
                } else if (item.roomid.equals(roomid)  && item.poker != null && item.sid.equals(sid) && item.poker.getCount() == 3) {
                    System.out.println("重连运行");
                    item.session = session;
                    reconnect = true;
                }
                // 房间人满
                if (this.poker != null && item.poker.getCount() == 3) {
                    //设置底牌
//                    this.poker.setBottom(bottom(this.poker.getStore()));
//                    System.out.println(bottom(this.poker.getStore()));

                    this.poker.getMap().put(Integer.MAX_VALUE - 10, bottom(this.poker.getStore()));
                    this.poker.getMap().put(Integer.MAX_VALUE - 11, new ArrayList<>());
                    this.poker.getOrder().add(0);
                    this.poker.getMap().put(Integer.MAX_VALUE - 12, this.poker.getOrder());
                    // 发牌
                    for (WebSocketServer launch : webSocketSet) {
                        if (launch.roomid.equals(roomid)) {
//                            System.out.println(launch.session == this.session);
                            launch.session.getBasicRemote().sendText(this.poker.toString());
                        }
                    }
                    this.session.getBasicRemote().sendText(this.poker.toString());
                }
            }
            // 如果房间没人 则创建Poker
            if (flag == false) {
                this.poker = new Poker(roomid, sid);
            }

            // webSockSet 储存每个访问路径不同的人
            if (reconnect != true) {
                webSocketSet.add(this);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public List<Integer> init(Map<Integer, Integer> store) {
        List<Integer> list = new ArrayList<>();
        Random random = new Random();

        while (list.size() < 17) {
            int i = random.nextInt(15) + 1;
            Integer integer = store.get(i);
            if (integer > 0) {
                store.put(i, integer - 1);
                list.add(i);
            }
        }
        return list;
    }

    public List<Integer> bottom(Map<Integer, Integer> store) {
        List<Integer> list = new ArrayList<>();
        for (int i = 1; i <= 15; i++) {
            if (store.get(i) > 0) {
                for (int j = 0; j < store.get(i); j++) {
                    list.add(i);
                }
            }
        }
//        System.out.println(list);
        return list;
    }

    @OnMessage
    public void onMessage(String message, Session session) {
//        System.out.println(message);
        if (message.charAt(0) == 'L') {
            message = message.substring(1);
            launch(message);
        } else if (message.charAt(0) == 'l') {
            message = message.substring(1);
            unLaunch(message);
        } else if (message.charAt(0) == 'Q') {
            message = message.substring(1);
            grab(message);
        } else if (message.charAt(0) == 'q') {
            message = message.substring(1);
            noGrab(message);
        } else if (message.charAt(0) == 'R') {
            message = message.substring(1);
            reset(message);
        } else if (message.charAt(0) == 'T') {
            message = message.substring(1);
            test(message);
        }

    }
    public void test(String message) {
//        System.out.println("收到心跳");
        for (WebSocketServer item : webSocketSet) {
            try {
                if (item.sid.equals(message)) {
                    item.session.getBasicRemote().sendText("Test");
                }
            } catch (IOException e) {
                e.printStackTrace();
            }

        }
    }
    public void reset(String message) {
        String roomid = "";
        String sid = "";
        for (WebSocketServer item : webSocketSet) {
            if (item.sid.equals(message)) {
                roomid = item.roomid;
                sid = item.sid;
                item.poker.setCount(item.poker.getCount() + 1);
                if ( item.poker.getCount() % 3 == 0) {
                    Map<Integer, Integer> temp = null;
                    for (WebSocketServer reset : webSocketSet) {
                        if (reset.roomid.equals(roomid)) {
                            Map<Integer, List<Integer>> map = reset.poker.getMap();
                            List<Integer> init = init(reset.poker.getStore());
                            this.poker.getMap().put(Integer.parseInt(reset.sid), init);
//                            System.out.println(reset.poker.getStore());
                            temp = reset.poker.getStore();
                        }
                    }
                    this.poker.getMap().put(Integer.MAX_VALUE - 10, bottom(temp));
                    this.poker.getMap().put(Integer.MAX_VALUE - 11, new ArrayList<>());
                    this.poker.getMap().put(Integer.MAX_VALUE - 12, this.poker.getOrder());
                    try {
                        // 发牌
                        for (WebSocketServer launch : webSocketSet) {
                            if (launch.roomid.equals(roomid)) {
                                launch.session.getBasicRemote().sendText(this.poker.toString());
                            }
                        }
                        this.session.getBasicRemote().sendText(this.poker.toString());
                    } catch (IOException e) {
                        e.printStackTrace();
                    }

                }
            }
        }
        for (WebSocketServer item : webSocketSet) {
            if (item.sid.equals(sid)) {
                Map<Integer, Integer> store = new HashMap<>();
                store.put(1, 4);
                store.put(2, 4);
                store.put(3, 4);
                store.put(4, 4);
                store.put(5, 4);
                store.put(6, 4);
                store.put(7, 4);
                store.put(8, 4);
                store.put(9, 4);
                store.put(10, 4);
                store.put(11, 4);
                store.put(12, 4);
                store.put(13, 4);
                store.put(14, 1);
                store.put(15, 1);
                item.poker.setStore(store);
            }
        }
    }

    public void launch(String message) {
        String[] split = message.split(",");
//        System.out.println(Arrays.toString(split));
        for (WebSocketServer item : webSocketSet) {
            try {
                // 出牌
//                System.out.println(item.poker.getMap());
                if (item.roomid.equals(split[0]) && item.sid.equals(split[1])) {
                    Map<Integer, List<Integer>> map = item.poker.getMap();
//                    System.out.println(map);
                    List<Integer> list = map.get(Integer.parseInt(split[1]));
                    List<Integer> crrent = new ArrayList<>();
                    // 移除出的手牌
                    for (int i = 2;  i < split.length; i++) {
                        list.remove((Integer)Integer.parseInt(split[i]));
                        crrent.add((Integer)Integer.parseInt(split[i]));
                    }
//                    System.out.println("list"+map);
                    map.put(Integer.parseInt(split[1]), list);
//                    System.out.println("crrent"+map);
                    map.put(Integer.MAX_VALUE - 11, crrent);

                    List<Integer> order = map.get(Integer.MAX_VALUE - 12);

                    for (int i = 0; i < order.size(); i++) {
                        if (order.get(i) == 0) {
                            order.remove((Integer)0);
                            order.remove((Integer)0);
                            order.add(1);
                        } else if(order.get(i) == 1) {
                            order.remove((Integer)1);
                            order.add(2);
                        } else if(order.get(i) == 2) {
                            order.remove((Integer)2);
                            order.add(0);
                        }
                    }

                    item.poker.setMap(map);
                    if (list.size() == 0) {
//                        System.out.println("运行");

                        for (WebSocketServer launch : webSocketSet) {
                            if (launch.roomid.equals(this.roomid)) {
                                launch.session.getBasicRemote().sendText("W"+item.sid);
                            }
                        }
                    } else {
                        System.out.println(webSocketSet.size());
                        for (WebSocketServer launch : webSocketSet) {
                            if (launch.roomid.equals(roomid)) {
                                System.out.println("出牌");
                                launch.session.getBasicRemote().sendText(launch.poker.toString());
                            }
                        }
                    }
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    public void unLaunch(String message) {
        String[] split = message.split(",");
//        System.out.println(Arrays.toString(split));
        for (WebSocketServer item : webSocketSet) {
            try {
                // 出牌
                if (item.roomid.equals(split[0]) && item.sid.equals(split[1])) {
                    Map<Integer, List<Integer>> map = item.poker.getMap();
//                    List<Integer> crrent = new ArrayList<>();
//                    map.put(Integer.MAX_VALUE - 11, crrent);
                    List<Integer> order = map.get(Integer.MAX_VALUE - 12);
                    for (int i = 0; i < order.size(); i++) {
                        if (order.get(i) == 0) {
                            order.remove((Integer)0);
                            order.remove((Integer)0);
                            order.add(1);
                        } else if(order.get(i) == 1) {
                            order.remove((Integer)1);
                            order.add(2);
                        } else if(order.get(i) == 2) {
                            order.remove((Integer)2);
                            order.add(0);
                        }
                    }
                    item.poker.setMap(map);
                    for (WebSocketServer launch : webSocketSet) {
                        if (launch.roomid.equals(roomid)) {
                            launch.session.getBasicRemote().sendText(this.poker.toString());
                        }
                    }
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }



    public void grab(String message) {
        String[] split = message.split(",");
//        System.out.println(Arrays.toString(split));
        for (WebSocketServer item : webSocketSet) {
            try {
                // 抢
                if (item.roomid.equals(split[0]) && item.sid.equals(split[1])) {
                    Map<Integer, List<Integer>> map = item.poker.getMap();
                    List<Integer> crrent = new ArrayList<>();
                    map.put(Integer.MAX_VALUE - 11, crrent);
//                    System.out.println(map.get(Integer.MAX_VALUE-10));
                    map.get(Integer.parseInt(split[1])).addAll(map.get(Integer.MAX_VALUE-10));
                    map.get(Integer.MAX_VALUE-10).clear();
//                    List<Integer> order = map.get(Integer.MAX_VALUE - 12);
//                    for (int i = 0; i < order.size(); i++) {
//                        if (order.get(i) == 0) {
//                            order.remove((Integer)0);
//                            order.remove((Integer)0);
//                            order.add(1);
//                        } else if(order.get(i) == 1) {
//                            order.remove((Integer)1);
//                            order.add(2);
//                        } else if(order.get(i) == 2) {
//                            order.remove((Integer)2);
//                            order.add(0);
//                        }
//                    }
                    item.poker.setMap(map);
                    for (WebSocketServer launch : webSocketSet) {
                        if (launch.roomid.equals(roomid)) {
                            launch.session.getBasicRemote().sendText(this.poker.toString());
                        }
                    }
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }


    public void noGrab(String message) {
        String[] split = message.split(",");
//        System.out.println(Arrays.toString(split));
        for (WebSocketServer item : webSocketSet) {
            try {
                // 不抢
                if (item.roomid.equals(split[0]) && item.sid.equals(split[1])) {
                    Map<Integer, List<Integer>> map = item.poker.getMap();
                    List<Integer> crrent = new ArrayList<>();
                    map.put(Integer.MAX_VALUE - 11, crrent);
                    List<Integer> order = map.get(Integer.MAX_VALUE - 12);
                    for (int i = 0; i < order.size(); i++) {
                        if (order.get(i) == 0) {
                            order.remove((Integer)0);
                            order.remove((Integer)0);
                            order.add(1);
                        } else if(order.get(i) == 1) {
                            order.remove((Integer)1);
                            order.add(2);
                        } else if(order.get(i) == 2) {
                            order.remove((Integer)2);
                            order.add(0);
                        }
                    }
                    item.poker.setMap(map);
                    for (WebSocketServer launch : webSocketSet) {
                        if (launch.roomid.equals(roomid)) {
                            launch.session.getBasicRemote().sendText(this.poker.toString());
                        }
                    }
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}
